package net.wanho.shop.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import net.wanho.shop.mapper.AttributeMapper;
import net.wanho.shop.mapper.CategoryMapper;
import net.wanho.shop.mapper.GoodsMapper;
import net.wanho.shop.po.Category;
import net.wanho.shop.service.CategoryService;
import net.wanho.shop.vo.CateGoryVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 分类表 服务实现类
 * </p>
 *
 * @author 猛虎王
 * @since 2024-12-24
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class CategoryServiceImpl implements CategoryService {

    private final CategoryMapper categoryMapper;
    private final GoodsMapper goodsMapper;
    private final AttributeMapper attributeMapper;

    /**
     * 分类表分页查询
     *
     * @param pageNum
     * @param pageSize
     * @param category
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    @Override
    public PageInfo findPage(int pageNum, int pageSize, Category category) {
        if (ObjectUtil.isNull(category)) {
            category = new Category();
        }

        // 分页
        PageHelper.startPage(pageNum, pageSize);
        List<Category> categoryList = categoryMapper.select(category);
        return new PageInfo(categoryList);
    }

    /**
     * 根据主键查询分类表
     *
     * @param catId
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    @Override
    public Category findById(Serializable catId) {
        return categoryMapper.selectById(catId);
    }

    /**
     * 分类表新增
     *
     * @param category
     */
    @Override
    public void add(Category category) {
        categoryMapper.insert(category);
    }

    /**
     * 修改分类表
     *
     * @param category
     */
    @Override
    public void modify(Category category) {
        categoryMapper.update(category);
    }

    /**
     * 根据主键删除分类表
     *
     * @param catId
     */
    @Override
    public void removeById(Integer catId) {

        int count = goodsMapper.selectByCatId(catId);
        if (count > 0)
            throw new RuntimeException("该分类下有商品，不能删除");
        // 删除列表
        List<Integer> deleteList = new ArrayList<>();
        // 添加当前分类
        deleteList.add(catId);
        // 递归查询子分类
        findCategory(catId, deleteList);
        // 首先将当前分类及子分类标记为删除（将sp_category表的cat_deleted设置为1）
        categoryMapper.updateDeleted(deleteList);
        // 然后将三级分类下的属性标记为删除（将sp_attribute表的delete_time设置为当前时间）
        attributeMapper.updateDeleteTimeByCayIds(deleteList);
    }

    private void findCategory(Integer catId, List<Integer> deleteIds) {
        List<Category> categories = categoryMapper.selectChildrenByPid(catId);
        categories.forEach(item -> {
            deleteIds.add(item.getCatId());
            // 递归
            findCategory(item.getCatId(), deleteIds);
        });
    }

    @Override
    public Object find(Integer pageNum, Integer pageSize, Integer type) {
//        List<Category> categories = categoryMapper.find(type);
        List<CateGoryVo> categories2 = categoryMapper.findType(type);
        // 不分页
        if (pageNum == null && pageSize == null) {
            // 查询所有
            List<CateGoryVo> list = categories2.stream()
                    .filter(item -> item.getCatLevel() == 0)
                    .map(item -> {
//                        CateGoryVo cateGoryVo = wrapper(item);
                        findChildren2(item, categories2);
                        return item;
                    }).collect(Collectors.toList());

            return list;
        }

        // 分页
        PageHelper.startPage(pageNum, pageSize);

        List<CateGoryVo> rootList = categoryMapper.findType(1); // 一级分类查询
        PageInfo<CateGoryVo> pageInfo = new PageInfo<>(rootList); // 分页对象

        // 封装数据
        List<CateGoryVo> list = rootList.stream()
                .map(item -> {
                    findChildren2(item, categories2);
                    return item;
                }).collect(Collectors.toList());

        Map<String, Object> map = new HashMap<>();
        map.put("total", pageInfo.getTotal());
        map.put("pageNum", pageInfo.getPageNum());
        map.put("pageSize", pageSize);
        map.put("list", list);


        return map;
    }

    @Override
    public void modifyByCatId(Category category, Integer catId) {
        Category category1 = categoryMapper.selectById(catId);
        if (category1 == null) {
            throw new RuntimeException("要修改的分类不存在");
        }


        categoryMapper.updateByCatId(category.getCatName(), catId);
    }

    private CateGoryVo wrapper(Category item) {
        CateGoryVo cateGoryVo = new CateGoryVo();
        cateGoryVo.setCatId(item.getCatId());
        cateGoryVo.setCatName(item.getCatName());
        cateGoryVo.setCatPid(item.getCatPid());
        cateGoryVo.setCatLevel(item.getCatLevel());
        return cateGoryVo;
    }

    private void findChildren(CateGoryVo item, List<Category> perms) {
        List<CateGoryVo> children = perms.stream()
                .filter(subItem -> subItem.getCatPid().equals(item.getCatId()))
                .map(subItem -> {
                    CateGoryVo permVo = wrapper(subItem);
                    findChildren(permVo, perms);
                    return permVo;
                }).collect(Collectors.toList());
        item.setChildren(children);

    }

    private void findChildren2(CateGoryVo item, List<CateGoryVo> perms) {
        List<CateGoryVo> children = perms.stream()
                .filter(subItem -> subItem.getCatPid().equals(item.getCatId()))
                .map(subItem -> {
                    findChildren2(subItem, perms);
                    return subItem;
                }).collect(Collectors.toList());
        item.setChildren(children);

    }
}
